package racegame.extensions;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import racegame.schedulerTasks.AutoCreateGamesTask;
import racegame.serverEvents.OnUserJoinZoneHandler;
import racegame.utils.WaitingList;

import com.smartfoxserver.v2.api.CreateRoomSettings;
import com.smartfoxserver.v2.api.CreateRoomSettings.RoomExtensionSettings;
import com.smartfoxserver.v2.core.SFSEventType;
import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSArray;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSArray;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.entities.variables.RoomVariable;
import com.smartfoxserver.v2.entities.variables.SFSRoomVariable;
import com.smartfoxserver.v2.entities.variables.VariableType;
import com.smartfoxserver.v2.exceptions.SFSJoinRoomException;
import com.smartfoxserver.v2.extensions.SFSExtension;

public class RaceGameZoneExtension extends SFSExtension {
	
	private ScheduledExecutorService scheduledExecutor;
	private ScheduledFuture<?> autoCreateGames = null;
	private WaitingList waitingPlayers;
	public Room lobby = null;
	
	
	@Override
	public void init() {
		
		trace("RaceGameZoneExtension Extension init.");
		
		addEventHandler(SFSEventType.USER_JOIN_ZONE ,   OnUserJoinZoneHandler.class);
		
		this.waitingPlayers = new WaitingList();
		this.lobby = this.getParentZone().getRoomByName("The Lobby");
		this.scheduledExecutor = Executors.newScheduledThreadPool(3);
		this.autoCreateGames = scheduledExecutor.scheduleAtFixedRate(
				new AutoCreateGamesTask(this), 5, 10, TimeUnit.SECONDS);
		
	}
	
	//Start new game with given IDs of players
	public void startGame(final ArrayList<Integer> userIds) {
		
		//Remove this players from waiting list
		for (int userID : userIds) {
			this.waitingPlayers.remove(userID);
		}
		
		//Create new room and join users in it
		String roomName = new Random().nextInt(200) + "" + new Random().nextInt(200) + " roomName";
		
		CreateRoomSettings crs = new CreateRoomSettings();
		crs.setName(roomName);
		crs.setMaxUsers(4);
		crs.setMaxVariablesAllowed(10);
		crs.setMaxSpectators(0);
		crs.setPassword("");
		crs.setDynamic(true);
		crs.setGame(true);
		crs.setExtension(new RoomExtensionSettings("RaceGameExtension", "racegame.extensions.RaceGameRoomExtension"));
		
		try {
			Room roomToJoin = getApi().createRoom(this.getParentZone(), crs, getApi().getUserById(userIds.get(0)));
			
			for (int userID : userIds) {
				User user = getApi().getUserById(userID);
				getApi().joinRoom(user, roomToJoin);
			}
			
			//Add player IDs to room variable
			SFSArray players = new SFSArray();
			players.addInt(getApi().getUserById(userIds.get(0)).getPlayerId());
			players.addInt(getApi().getUserById (userIds.get(1)).getPlayerId());
			
			ArrayList<RoomVariable> roomVariables = new ArrayList<RoomVariable>();
			roomVariables.add(new SFSRoomVariable("players", players));
			getApi().setRoomVariables(null, roomToJoin, roomVariables);
			
			
		} catch (Exception e) {
			trace("Error when creating room and joining players in it !");
			e.printStackTrace();
		}
		
		
	}
	
	//Add user that joined the zone to the waiting list and join him in Lobby room
	public void addUserToWaitingList(User userToAdd) {
		
		try {
			getApi().joinRoom(userToAdd, this.lobby);
		} catch (SFSJoinRoomException e) {
			trace("User: " + userToAdd.getId() + " could not join Lobby room !" );
			e.printStackTrace();
		}
		
		waitingPlayers.addUser(userToAdd);
		
	}
	
	public WaitingList getWaitingList() {
		
		return waitingPlayers;
		
	}
	
	@Override
	public void destroy() 
	{
		
		super.destroy();
		trace("RaceGameZoneExtension destroyed.");
		
	}

}
